<template>
  <div class="flow-container">
    <div class="scale-slider">
      <el-icon class="btn" @click="changeScale(step)">
        <Plus/>
      </el-icon>
      <span style="font-size:14px;">{{ scaleVal }}%</span>
      <el-icon class="btn" @click="changeScale(-step)">
        <Minus/>
      </el-icon>
    </div>
    <FlowCard
        :verifyMode="verifyMode"
        :key="updateId"
        :data="data"
        @emits="eventReciver"
        :style="{ transform: `scale(${scaleVal / 100})` }"
    />
    <PropPanel
        :value="activeData"
        :processData="data"
        @confirm="onPropEditConfirm"
        @cancel="onClosePanel"
    />
  </div>
</template>
<script setup name="Process">
import FlowCard from "./FlowCard/index.vue";
import PropPanel from "./PropPanel/index.vue";

import {
  NodeUtils,
  getMockData
} from "./FlowCard/util.js";
import {ElIcon} from 'element-plus';
const emits = defineEmits(['startNodeChange']);
// 定义 props
const props = defineProps({
  tabName: String,
  conf: Object
});
// 定义数据
const data = ref({});
const scaleVal = ref(100);
const step = ref(5);
const updateId = ref(0);
const activeData = ref(null);
const isProcessCmp = ref(true);
const verifyMode = ref(false);
// 初始化数据
const initData = () => {

  let mockData = getMockData();
  if (typeof props.conf === 'object' && props.conf !== null) {
    Object.assign(mockData,
        props.conf);
  }
  data.value = mockData;
};
initData();
// 给父级组件提供的获取流程数据得方法
const getData = () => {
  verifyMode.value = true;
  if (NodeUtils.checkAllNode(data.value)) {
    return Promise.resolve({formData: data.value});
  } else {
    return Promise.reject({target: props.tabName});
  }
};
// 接收所有 FlowCard 事件触发
const eventReciver = ({
                        event,
                        args
                      }) => {

  if (event === "edit") {
    activeData.value = args[0]; // 打开属性面板
    return;
  }
  NodeUtils[event](...args);
  forceUpdate();
};
// 强制更新
const forceUpdate = () => {
  updateId.value = updateId.value + 1;
};
// 控制流程图缩放
const changeScale = (val) => {
  let v = scaleVal.value + val;
  if (v > 0 && v <= 200) {
    // 缩放介于 0%~200%
    scaleVal.value = v;
  }
};
// 属性面板提交事件
const onPropEditConfirm = (value,
                           content) => {

  activeData.value.content = content || '请设置条件';
  let oldProp = activeData.value.properties;
  activeData.value.properties = value;
  // 修改优先级
  if (NodeUtils.isConditionNode(activeData.value)) {
    if (value.priority !== oldProp.priority) {
      NodeUtils.resortPrioByCNode(
          activeData.value,
          oldProp.priority,
          data.value
      );
    }
    NodeUtils.setDefaultCondition(activeData.value,
        data.value);
  }
  if (NodeUtils.isStartNode(activeData.value)) {

    emits('startNodeChange',
        data.value);
  }
  onClosePanel();
  forceUpdate();
};
// 属性面板取消事件
const onClosePanel = () => {
  activeData.value = null;
};
// 传 formIds 查询指定组件 未传时 判断所有组件
const isFilledPCon = (formIds) => {
  let res = false;
  const loopChild = (parent,
                     callback) => parent.childNode && loop(parent.childNode,
      callback);
  const loop = (data,
                callback) => {
    if (res || !data) return; // 查找到就退出
    if (Array.isArray(data.conditionNodes)) {
      const uesd = data.conditionNodes.some(c => {
        const cons = c.properties.conditions || [];
        return Array.isArray(formIds)
            ? cons.some(item => formIds.includes(item.formId)) // 查询特定组件
            : cons.length > 0; // 只要有节点设置了条件 说明就有组件作为条件被使用
      });
      uesd ? callback() : data.conditionNodes.forEach(t => loopChild(t,
          callback));
    }
    loopChild(data,
        callback);
  };
  loop(data.value,
      () => res = true);
  return res;
};
defineExpose({
  getData
});
</script>
<style scoped lang="scss">
$bg-color: #f5f5f7;
.flow-container {
  display: inline-block;
  background: $bg-color;
  padding: 20px;
  width: 100%;
  height: 100%;
  box-sizing: border-box;
  text-align: center;
  overflow: auto;
}

.scale-slider {
  position: fixed;
  right: 20px;
  z-index: 99;
  display: inline-flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;

  .btn {
    display: inline-flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    width: 28px;
    height: 28px;
    padding: 4px;
    border: 1px solid #cacaca;
    border-radius: 3px;
    background: #FFF;
    margin-left: 10px;
    margin-right: 10px;
    cursor: pointer;
    color: #2c3e50;
  }
}
</style>
